package com.jc.nio.server;

import java.net.InetSocketAddress;
import java.nio.channels.ServerSocketChannel;

import com.jc.nio.log.LogAdviceImpl;
import com.jc.nio.log.ProxyFactory;
import com.jc.nio.thread.AcceptorGroup;
import com.jc.nio.thread.WorkerGroup;

/**
 * 这个类相当于tomcat中的NioEndpoint
 * 
 * @author Joeson
 * @since 2014/05
 * @version 01
 * @param <WorkerGroup>
 * 
 */
public class Connector implements Runnable
{
	private ServerSocketChannel serverSocket = null;

	/**
	 * 端口
	 */
	private int port = 8080;

	/**
	 * 当前状态
	 */
	private int state;
	/**
	 * 状态运行
	 */
	private volatile boolean running = true;
	/**
	 * 状态停止
	 */
	private volatile boolean paused = false;

	/**
	 * 处理通道连接的集合
	 */
	private AcceptorGroup acceptGroup = null;
	/**
	 * 处理通道的线程集合
	 */
	private WorkerGroup workerGroup = null;

	/**
	 * 默认的acceptor处理线程数目
	 */
	private static final int defaultAcceptorSize = Math.min(2, Runtime
			.getRuntime().availableProcessors());

	/**
	 * 处理线程数目
	 */
	private int acceptorSize;

	/**
	 * 默认的处理woker线程的数目
	 */
	private static final int defaultWorkerSize = Math.min(2, Runtime
			.getRuntime().availableProcessors());

	/**
	 * 接受线程的数目
	 */
	private int workerSize;

	/**
	 * 如果accetorSize、port、workSize都不为空，那么设置为给定值
	 * 
	 * @param port
	 *            监听端口号
	 * @param acceptorSize
	 *            接受线程数
	 * @param workerSize
	 *            工作处理线程数
	 * @throws Exception
	 */
	public Connector(int port, int acceptorSize, int workerSize)
			throws Exception
	{

		if (port != 0)
		{
			this.port = port;
		}

		if (acceptorSize == 0)
		{
			acceptorSize = defaultAcceptorSize;
		}
		else
		{
			this.acceptorSize = acceptorSize;
		}

		if (workerSize == 0)
		{
			workerSize = defaultWorkerSize;
		}
		else
		{
			this.workerSize = workerSize;
		}

		// 先初始化并设置serversocketchannel
		serverSocket = ServerSocketChannel.open();
		serverSocket.bind(new InetSocketAddress(port));
		serverSocket.configureBlocking(false);

		workerGroup = new WorkerGroup(workerSize);
		acceptGroup = new AcceptorGroup(acceptorSize, serverSocket, workerGroup);
	}

	public void run()
	{

		// 判断是否停止操作，在本例子中并没有需要操作的业务逻辑，不过可以以后拓展
		while (running)
		{
			if (paused)
			{
				acceptGroup.paused();
			}
			try
			{
				Thread.currentThread().sleep(1000);
			} catch (InterruptedException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	public static void main(String... args) throws Exception
	{
		Runnable server = ProxyFactory.getProxy(new Connector(8081, 2, 10),new LogAdviceImpl());
		new Thread(server).start();
	}
}